#include "modbus.h"
#include "stm32f429xx.h"
#include "globals.h"
#include "netpacket.h"
#include "FreeRTOS.h"
#include "task.h"

const char modbus_err_pull_caption[] = {"E_FF"};
const char modbus_err_crc_caption[] = {"E_01"};
const char modbus_err_malformerPacket_caption[] = {"E_02"};

sModbusReq modbusReq;
void ModbusModeSet(uint8_t direct, uint8_t channel);
void ModbusStartTxDMA(uint8_t * data, uint8_t len);
void Modbus_SetModeDirection(uint8_t direct);

UART_HandleTypeDef UartHandle;

/****************************/
/* Modbus Init				*/
/****************************/
void ModbusInit(void)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	RCC->MODBUS_GPIO_RCC_AHB |= MODBUS_GPIO_RCC_EN;
	// General USART RX
	GPIO_InitStruct.Pin = MODBUS_RX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Alternate = MODBUS_RX_AF;
	GPIO_InitStruct.Speed = GPIO_SPEED_FAST;
	HAL_GPIO_Init(MODBUS_RX_PORT, &GPIO_InitStruct);
	// General USART TX
	GPIO_InitStruct.Pin = MODBUS_TX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Alternate = MODBUS_RX_AF;
	HAL_GPIO_Init(MODBUS_TX_PORT, &GPIO_InitStruct);
	// RAW RX Input
	GPIO_InitStruct.Pin = MODBUS_RAW_OUT_RX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_RAW_OUT_RX_PORT, &GPIO_InitStruct);
	// RAW TX Output
	GPIO_InitStruct.Pin = MODBUS_RAW_IN_TX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_RAW_IN_TX_PORT, &GPIO_InitStruct);

	// Channel 0 RX
	GPIO_InitStruct.Pin = MODBUS_CHANNEL0_RX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL0_RX_PORT, &GPIO_InitStruct);
	// Channel 0 TX
	GPIO_InitStruct.Pin = MODBUS_CHANNEL0_TX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL0_TX_PORT, &GPIO_InitStruct);
	// Channel 0 RE
	GPIO_InitStruct.Pin = MODBUS_CHANNEL0_RE_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL0_RE_PORT, &GPIO_InitStruct);

	// Channel 1 RX
	GPIO_InitStruct.Pin = MODBUS_CHANNEL1_RX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL1_RX_PORT, &GPIO_InitStruct);
	// Channel 1 TX
	GPIO_InitStruct.Pin = MODBUS_CHANNEL1_TX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL1_TX_PORT, &GPIO_InitStruct);
	// Channel 1 RE
	GPIO_InitStruct.Pin = MODBUS_CHANNEL1_RE_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL1_RE_PORT, &GPIO_InitStruct);

	// Channel 2 RX
	GPIO_InitStruct.Pin = MODBUS_CHANNEL2_RX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL2_RX_PORT, &GPIO_InitStruct);
	// Channel 2 TX
	GPIO_InitStruct.Pin = MODBUS_CHANNEL2_TX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL2_TX_PORT, &GPIO_InitStruct);
	// Channel 2 RE
	GPIO_InitStruct.Pin = MODBUS_CHANNEL2_RE_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL2_RE_PORT, &GPIO_InitStruct);

	// Channel 3 RX
	GPIO_InitStruct.Pin = MODBUS_CHANNEL3_RX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	GPIO_InitStruct.Pull = GPIO_PULLDOWN;
	HAL_GPIO_Init(MODBUS_CHANNEL3_RX_PORT, &GPIO_InitStruct);
	// Channel 3 TX
	GPIO_InitStruct.Pin = MODBUS_CHANNEL3_TX_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL3_TX_PORT, &GPIO_InitStruct);
	// Channel 3 RE
	GPIO_InitStruct.Pin = MODBUS_CHANNEL3_RE_PIN;
	GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	HAL_GPIO_Init(MODBUS_CHANNEL3_RE_PORT, &GPIO_InitStruct);

	/* Init USART RAW timer */
	MODBUS_TIMER_ENABLE;
	MODBUS_TIMER->CCER |= TIM_CCER_CC1E;
	MODBUS_TIMER->DIER |= TIM_DIER_UIE;
	MODBUS_TIMER->PSC = 0x50;
	MODBUS_TIMER->ARR = 0x5;
	HAL_NVIC_SetPriority(MODBUS_TIMER_IRQn, 3, 0);
	HAL_NVIC_EnableIRQ(MODBUS_TIMER_IRQn);

	/* Enable USART clock */
	MODBUS_USARTx_CLK_ENABLE();

	UartHandle.Instance          = MODBUS_USART;
	UartHandle.Init.BaudRate     = BAUD9600;
	UartHandle.Init.WordLength   = UART_WORDLENGTH_8B;
	UartHandle.Init.StopBits     = UART_STOPBITS_1;
	UartHandle.Init.Parity       = UART_PARITY_NONE;
	UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
	UartHandle.Init.Mode         = UART_MODE_TX_RX;
	UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;
	HAL_UART_Init(&UartHandle);

	/* NVIC configuration for USART TC interrupt */
	HAL_NVIC_SetPriority(MODBUS_USART_IRQn, 1, 0);
	HAL_NVIC_EnableIRQ(MODBUS_USART_IRQn);

	if(xTaskCreate(ModbusTask, NULL, 384, NULL, tskIDLE_PRIORITY+2, NULL) != pdPASS)
		Error_Handler();

	Modbus_SetModeDirection(E_MODBUS_DIRECT_NON);

	modbusReq.state = 0;
}

void Modbus_SetBaudrate(uint8_t baud)
{
	UartHandle.Instance          = MODBUS_USART;
	UartHandle.Init.WordLength   = UART_WORDLENGTH_8B;
	UartHandle.Init.StopBits     = UART_STOPBITS_1;
	UartHandle.Init.Parity       = UART_PARITY_NONE;
	UartHandle.Init.HwFlowCtl    = UART_HWCONTROL_NONE;
	UartHandle.Init.Mode         = UART_MODE_TX_RX;
	UartHandle.Init.OverSampling = UART_OVERSAMPLING_16;

	switch(baud)
	{
	case E_MODBUS_BAUD2400:  UartHandle.Init.BaudRate = BAUD2400; break;
	case E_MODBUS_BAUD4800:  UartHandle.Init.BaudRate = BAUD4800; break;
	case E_MODBUS_BAUD9600:  UartHandle.Init.BaudRate = BAUD9600; break;
	case E_MODBUS_BAUD19200: UartHandle.Init.BaudRate = BAUD19200; break;
	default : UartHandle.Init.BaudRate = BAUD9600; break;
	}

	HAL_UART_Init(&UartHandle);
}

void Modbus_SetModeDirection(uint8_t direct)
{
	if(direct == E_MODBUS_DIRECT_TX)
	{
		__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_TC);
		__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);

		switch(modbusReq.channel)
		{
		case E_MODBUS_CHANNEL_0: MODBUS_CHANNEL0_RE_PORT->ODR |= MODBUS_CHANNEL0_RE_PIN; break;
		case E_MODBUS_CHANNEL_1: MODBUS_CHANNEL1_RE_PORT->ODR |= MODBUS_CHANNEL1_RE_PIN; break;
		case E_MODBUS_CHANNEL_2: MODBUS_CHANNEL2_RE_PORT->ODR |= MODBUS_CHANNEL2_RE_PIN; break;
		case E_MODBUS_CHANNEL_3: MODBUS_CHANNEL3_RE_PORT->ODR |= MODBUS_CHANNEL3_RE_PIN; break;
		default : break;
		}

		LED_GREEN_0;
		MODBUS_TIMER->CR1 |= TIM_CR1_CEN;
		HAL_NVIC_EnableIRQ(MODBUS_TIMER_IRQn);
		modbusReq.rxLeng = 0;
		modbusReq.txCounter = 0;
		/* start transmit */
		MODBUS_USART->DR = modbusReq.tx_buf[0];
		modbusReq.txCounter ++;
	}
	if(direct == E_MODBUS_DIRECT_RX)
	{
		__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC);
		__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);

		switch(modbusReq.channel)
		{
		case E_MODBUS_CHANNEL_0: MODBUS_CHANNEL0_RE_PORT->ODR &=~ MODBUS_CHANNEL0_RE_PIN; break;
		case E_MODBUS_CHANNEL_1: MODBUS_CHANNEL1_RE_PORT->ODR &=~ MODBUS_CHANNEL1_RE_PIN; break;
		case E_MODBUS_CHANNEL_2: MODBUS_CHANNEL2_RE_PORT->ODR &=~ MODBUS_CHANNEL2_RE_PIN; break;
		case E_MODBUS_CHANNEL_3: MODBUS_CHANNEL3_RE_PORT->ODR &=~ MODBUS_CHANNEL3_RE_PIN; break;
		default : break;
		}
		__HAL_UART_ENABLE_IT(&UartHandle, UART_IT_RXNE);
		MODBUS_TIMER->CR1 |= TIM_CR1_CEN;
		HAL_NVIC_EnableIRQ(MODBUS_TIMER_IRQn);
		modbusReq.rxLeng = 0;
	}

	if(direct == E_MODBUS_DIRECT_NON )
	{
		__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_TC);
		__HAL_UART_DISABLE_IT(&UartHandle, UART_IT_RXNE);
		MODBUS_CHANNEL0_RE_PORT->ODR &=~ MODBUS_CHANNEL0_RE_PIN;
		MODBUS_CHANNEL1_RE_PORT->ODR &=~ MODBUS_CHANNEL1_RE_PIN;
		MODBUS_CHANNEL2_RE_PORT->ODR &=~ MODBUS_CHANNEL2_RE_PIN;
		MODBUS_CHANNEL3_RE_PORT->ODR &=~ MODBUS_CHANNEL3_RE_PIN;

		LED_GREEN_1;
		MODBUS_TIMER->CR1 &=~ TIM_CR1_CEN;
		MODBUS_USART->SR =0;
		HAL_NVIC_DisableIRQ(MODBUS_TIMER_IRQn);
	}
}

void MODBUS_USART_IRQHandler(void)
{
	if(MODBUS_USART->SR & USART_SR_RXNE)
	{
		if(modbusReq.rxLeng < sizeof(modbusReq.rx_buf))
		{
			modbusReq.rx_buf[modbusReq.rxLeng] = MODBUS_USART->DR;
			modbusReq.rxLeng++;
		}
		modbusReq.state |= E_MODBUS_STATE_RX_BUSY;
	}
	if(MODBUS_USART->SR & USART_SR_TC)
	{
		if(modbusReq.txCounter < modbusReq.txLeng )
		{
			MODBUS_USART->DR =  modbusReq.tx_buf[modbusReq.txCounter];
			modbusReq.txCounter ++;
		}
		else
			modbusReq.state |= E_MODBUS_STATE_TX_COMPLETE;
	}
	MODBUS_USART->SR = 0;
}

uint8_t ModbusReplyHandler(uint8_t *data, uint8_t leng, sParamSecondary* sec, uint8_t crc_state)
{
	uint16_t i;
	uint16_t i2;
	uint16_t i3;
	uint8_t marker;
	uint8_t *p;
	uint8_t nullCounter;

	/* Insert Reply data */

	/* ID modbus line */
	i = strlen((char*)&netStruct.netPacket);
	sprintf((char*)&netStruct.netPacket[i], "%x", startParam.modbus_id_lines[sec->channel]);

	/* separator */
	i = strlen((char*)&netStruct.netPacket);
	netStruct.netPacket[i++] = ',';

	/* Copy Device Caption */
	i = strlen((char*)&netStruct.netPacket);
	for(i2=0; i2<sizeof(sec->deviceCaption); i2++)
	{
		if(sec->deviceCaption[i2] == 0)
			break;
		netStruct.netPacket[i++] = sec->deviceCaption[i2];
	}

	/* separator */
	i = strlen((char*)&netStruct.netPacket);
	netStruct.netPacket[i++] = ',';

	/* Copy ID */
	for(i2=0; i2<sec->leng_id; i2++)
	{
		i = strlen((char*)&netStruct.netPacket);
		sprintf((char*)&netStruct.netPacket[i], "%x", sec->reqData[i2]);
	}

	/* separator */
	i = strlen((char*)&netStruct.netPacket);
	netStruct.netPacket[i++] = ':';

	/* Copy Request Capion*/
	i = strlen((char*)&netStruct.netPacket);
	for(i2=0; i2<sizeof(sec->reqCaption); i2++)
	{
		if(sec->reqCaption[i2] == 0)
			break;
		netStruct.netPacket[i++] = sec->reqCaption[i2];
	}

	/* separator */
	i = strlen((char*)&netStruct.netPacket);
	netStruct.netPacket[i++] = '_';

	if(crc_state == E_MODBUS_CRC_OK)
	{
		/* Parsing markers separator packet */
		marker = 0;
		for(i2=0; i2<sec->markers.replyMarckersAll; i2++)
		{
			/* Copy reply request */
			p = data;
			p += sec->markers.marckerStart[marker];
			nullCounter = 0;
			for(i3=(sec->markers.marckerStart[marker]); i3<(sec->markers.marckerStart[marker] + sec->markers.marckerLeng[marker]); i3++)
			{
				i = strlen((char*)&netStruct.netPacket);
				if((nullCounter != 0) || ((*p)!=0))
				{
					sprintf((char*)&netStruct.netPacket[i], "%x", (*p));
					nullCounter =1;
				}
				p++;
			}
			if(nullCounter == 0)
				netStruct.netPacket[i++] = '0';
			i = strlen((char*)&netStruct.netPacket);
			netStruct.netPacket[i++] = ',';
			marker ++;
		}
		netStruct.netPacket[--i] = 0;
	}
	else
	{
		if(leng != 0)
			strcpy(&netStruct.netPacket[i], modbus_err_crc_caption);
		else
			strcpy(&netStruct.netPacket[i], modbus_err_pull_caption);
	}

	i = strlen((char*)&netStruct.netPacket);
	netStruct.netPacket[i++] = '-';

	return E_OK;
}

void ModbusPollHanler(void)
{
	uint8_t i=0;
	uint16_t i16;
	uint32_t blockCounter=0;
	sParamSecondary paramSecondary;
	sParamGeneral paramGeneral;

	while(1)
	{
		/* if run mode Alarm - read sequence desicrioptors */
		if( modbusReq.state & E_MODBUS_STATE_START_ALARM )
		{
			Flash_M25P64_Read_Buffer((uint8_t*)&paramGeneral, ADDRESS_PARAM_GENERAL, sizeof(paramGeneral));
			blockCounter += 256;
			Flash_M25P64_Read_Buffer((uint8_t*)&paramSecondary, blockCounter, sizeof(paramSecondary));
			/* Set baudrate, currnet line */
			Modbus_SetBaudrate(paramGeneral.modbus_baudrate[paramSecondary.channel]);
		}
		else
			Modbus_SetBaudrate(modbusReq.baudrate);

		/* if parameters incorect, goto error */
		if((paramSecondary.final != FINAL_OK) && (modbusReq.state & E_MODBUS_STATE_START_ALARM ))
			goto endPoll;

		if( modbusReq.state & E_MODBUS_STATE_START_ALARM )
		{
			/* copy request data to poll struct*/
			for(i=0; i < (paramSecondary.reqLeng); i++)
				modbusReq.tx_buf[i] = paramSecondary.reqData[i];
			/* get leng buffer tx */
			modbusReq.txLeng = i;
			modbusReq.channel = paramSecondary.channel;
		}

		/* calc CRC16*/
		i16 = getCRC((uint8_t*)&modbusReq.tx_buf, modbusReq.txLeng);
		modbusReq.tx_buf[modbusReq.txLeng++] = i16 & 0x00FF;
		modbusReq.tx_buf[modbusReq.txLeng++] = (i16 & 0xFF00)>>8;
		modbusReq.crc_state = 0;
		/* tune transmit */
		Modbus_SetModeDirection(E_MODBUS_DIRECT_TX);
		/* Preparation Transmit */
		modbusReq.state |= E_MODBUS_STATE_TX;
		modbusReq.state &=~ E_MODBUS_STATE_TX_COMPLETE;
		/* while Transfer not compete */
		while(!( modbusReq.state & E_MODBUS_STATE_TX_COMPLETE));
		/* set direct Receive */
		Modbus_SetModeDirection(E_MODBUS_DIRECT_RX);

		/* while Reply not complete */
		vTaskDelay(150);

		Modbus_SetModeDirection(E_MODBUS_DIRECT_NON);

		/* check reply */
		if(modbusReq.rxLeng >= MODBUS_MINIMAL_CORECT_PACKET)
		{
			i16 = getCRC((uint8_t*)&modbusReq.rx_buf, modbusReq.rxLeng-2);

			if( ( ( i16 & 0xFF ) != modbusReq.rx_buf[modbusReq.rxLeng-2] ) && ( ( ( i16 & 0xFF00) >>8) != modbusReq.rx_buf[modbusReq.rxLeng-1] ) )
				/* CRC error */
				modbusReq.crc_state = E_MODBUS_CRC_ERROR;
			else
				modbusReq.crc_state = E_MODBUS_CRC_OK;
		}
		else
			modbusReq.crc_state = E_MODBUS_CRC_ERROR;

		if(modbusReq.state & E_MODBUS_STATE_START_ALARM)
		{
			/* if error network connection, goto end poll */
			if(ModbusReplyHandler((uint8_t*)&modbusReq.rx_buf, modbusReq.rxLeng-2, &paramSecondary, modbusReq.crc_state) == E_OK)
			{
				if(NetworkModbusCheckBuffer())
					NetworkModbusAction(E_NETWORK_MODBUS_SEND);
			}
			else
				goto endPoll;
		}
		else
			goto endPoll;
	};
	endPoll:
	modbusReq.state =0;
}

void ModbusTask(void *pvParameters)
{
	if(bootMode != BOOT_MODE_USB)
		RTC_AlarmConfig();

	for(;;)
	{
		/* start DMA transmit, if set flag */
		if( modbusReq.state & E_MODBUS_STATE_START_ALARM )
		{
			if((dateTimeNext == 0)&&(modbusReq.state & E_MODBUS_STATE_START_ALARM) &&(bootMode != BOOT_MODE_USB))
			{
				/* Network connect Up */
				if(NetworkModbusAction(E_NETWORK_MODBUS_UP) == E_OK)
				{
					/* polling function */
					ModbusPollHanler();
					/* Send 'END' captions */
					NetworkModbusAction(E_NETWORK_MODBUS_SEND_END);
					/* Close connect network */
					NetworkModbusAction(E_NETWORK_MODBUS_DOWN);
				}
				RTC_AlarmConfig();
				RTC_Set_Next_Time();
			}
			modbusReq.state =0;
		}

		if(modbusReq.state & E_MODBUS_STATE_START_MANUAL)
			/* polling function */
			ModbusPollHanler();

		/* Led off */
		LED_GREEN_1;
		vTaskDelay(500);
	}
}

void MODBUS_TIMER_IRQHandler(void)
{
	/* Transmit */
	if(MODBUS_RAW_IN_TX_PORT->IDR & MODBUS_RAW_IN_TX_PIN)
	{
		switch(modbusReq.channel)
		{
		case E_MODBUS_CHANNEL_0: MODBUS_CHANNEL0_TX_PORT->ODR |= MODBUS_CHANNEL0_TX_PIN; break;
		case E_MODBUS_CHANNEL_1: MODBUS_CHANNEL1_TX_PORT->ODR |= MODBUS_CHANNEL1_TX_PIN; break;
		case E_MODBUS_CHANNEL_2: MODBUS_CHANNEL2_TX_PORT->ODR |= MODBUS_CHANNEL2_TX_PIN; break;
		case E_MODBUS_CHANNEL_3: MODBUS_CHANNEL3_TX_PORT->ODR |= MODBUS_CHANNEL3_TX_PIN; break;
		default : break;
		}
	}
	else
	{
		switch(modbusReq.channel)
		{
		case E_MODBUS_CHANNEL_0: MODBUS_CHANNEL0_TX_PORT->ODR &=~ MODBUS_CHANNEL0_TX_PIN; break;
		case E_MODBUS_CHANNEL_1: MODBUS_CHANNEL1_TX_PORT->ODR &=~ MODBUS_CHANNEL1_TX_PIN; break;
		case E_MODBUS_CHANNEL_2: MODBUS_CHANNEL2_TX_PORT->ODR &=~ MODBUS_CHANNEL2_TX_PIN; break;
		case E_MODBUS_CHANNEL_3: MODBUS_CHANNEL3_TX_PORT->ODR &=~ MODBUS_CHANNEL3_TX_PIN; break;
		default : break;
		}
	}

	/* Receive */
	switch(modbusReq.channel)
	{
	case E_MODBUS_CHANNEL_0: if(MODBUS_CHANNEL0_RX_PORT->IDR & MODBUS_CHANNEL0_RX_PIN) MODBUS_RX_RAW_SET_1; else MODBUS_RX_RAW_SET_0; break;
	case E_MODBUS_CHANNEL_1: if(MODBUS_CHANNEL1_RX_PORT->IDR & MODBUS_CHANNEL1_RX_PIN) MODBUS_RX_RAW_SET_1; else MODBUS_RX_RAW_SET_0; break;
	case E_MODBUS_CHANNEL_2: if(MODBUS_CHANNEL2_RX_PORT->IDR & MODBUS_CHANNEL2_RX_PIN) MODBUS_RX_RAW_SET_1; else MODBUS_RX_RAW_SET_0; break;
	case E_MODBUS_CHANNEL_3: if(MODBUS_CHANNEL3_RX_PORT->IDR & MODBUS_CHANNEL3_RX_PIN) MODBUS_RX_RAW_SET_1; else MODBUS_RX_RAW_SET_0; break;
	default : break;
	}

	MODBUS_TIMER->SR = 0;
}
